﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;

namespace IOA.MES.Client.Common
{
    public class HttpHelper
    {
        private enum HttpType
        {
            POST, GET, PUT
        }
        public string ContentType { get; set; }
        public Dictionary<string, string> DictHeaders { get; set; }
        public CookieCollection Cookies { get; set; }
        public int TimeOut { get; set; }
        public string UserAgent { get; set; }

        private HttpWebRequest GetRequest(string url, HttpType httpType)
        {
            var request = WebRequest.Create(url) as HttpWebRequest;
            request.Method = httpType.ToString();
            if (httpType == HttpType.POST)
            {
                request.ContentType = string.IsNullOrWhiteSpace(ContentType) ? "application/x-www-form-urlencoded" : ContentType;
            }

            //设置代理UserAgent和超时
            if (!string.IsNullOrWhiteSpace(UserAgent))
            {
                request.UserAgent = UserAgent;
            }
            if (TimeOut > 0)
            {
                request.Timeout = TimeOut;
            }

            request.Headers.Add("ClientVersion", FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location).ProductVersion);
            if (!(DictHeaders == null || DictHeaders.Count == 0))
            {
                foreach (var header in DictHeaders)
                {
                    switch (header.Key.ToLower())
                    {
                        case "content-type":
                            request.ContentType = header.Value;
                            break;
                        case "user-agent":
                            request.UserAgent = header.Value;
                            break;
                        case "connection":
                            request.Connection = header.Value;
                            break;
                        default:
                            request.Headers.Add(header.Key, header.Value);
                            break;
                    }
                }
            }
            if (Cookies != null)
            {
                request.CookieContainer = new CookieContainer();
                request.CookieContainer.Add(Cookies);
            }

            return request;
        }

        /// <summary>
        /// POST请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="dictParas">请求参数集</param>
        /// <returns>返回结果</returns>
        public string PostParas(string url, Dictionary<string, string> dictParas)
        {
            var request = GetRequest(url, HttpType.POST);

            if (!(dictParas == null || dictParas.Count == 0))
            {
                var paras = string.Join("&", dictParas.Select(_ => $"{_.Key}={_.Value}"));
                byte[] data = Encoding.UTF8.GetBytes(paras);
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            return GetResponseString(request.GetResponse() as HttpWebResponse);
        }

        /// <summary>
        /// POST请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="postData">请求内容</param>
        /// <returns>返回结果</returns>
        public string PostData(string url, string postData)
        {
            var request = GetRequest(url, HttpType.POST);
            //发送POST数据  
            if (!string.IsNullOrWhiteSpace(postData))
            {
                byte[] data = Encoding.UTF8.GetBytes(postData);
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            return GetResponseString(request.GetResponse() as HttpWebResponse);
        }

        /// <summary>
        /// POST请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="obj">请求对象</param>
        /// <returns>返回结果</returns>
        public string PostJson(string url, object obj)
        {
            var request = GetRequest(url, HttpType.POST);
            request.ContentType = "application/json;charset=utf-8";
            //发送POST数据  
            if (obj != null)
            {
                byte[] data = Encoding.UTF8.GetBytes(Newtonsoft.Json.JsonConvert.SerializeObject(obj));
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            return GetResponseString(request.GetResponse() as HttpWebResponse);
        }

        /// <summary>
        /// 发起HttpGet请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="dictParas">请求参数集</param>
        /// <returns>返回结果</returns>
        public string CreateGet(string url, Dictionary<string, string> dictParas)
        {
            var request = GetRequest(url, HttpType.GET);

            //组装参数  
            if (!(dictParas == null || dictParas.Count == 0))
            {
                var paras = string.Join("&", dictParas.Select(_ => $"{_.Key}={_.Value}"));
                url = url.LastIndexOf("?") < 0 ? (url + "?" + paras) : (url.EndsWith("?") ? url + paras : url + "?" + paras);
            }

            return GetResponseString(request.GetResponse() as HttpWebResponse);
        }

        /// <summary>
        /// 获取请求的数据
        /// </summary>
        private string GetResponseString(HttpWebResponse webresponse)
        {
            using (var s = webresponse.GetResponseStream())
            {
                if (string.Equals(webresponse.ContentEncoding, "gzip", StringComparison.CurrentCultureIgnoreCase))
                {
                    var zipStream = new GZipStream(s, CompressionMode.Decompress);
                    var ms = new MemoryStream();
                    byte[] bytes = new byte[40960];
                    int n;
                    while ((n = zipStream.Read(bytes, 0, bytes.Length)) > 0)
                    {
                        ms.Write(bytes, 0, n);
                    }
                    zipStream.Close();
                    ms.Position = 0;
                    var reader = new StreamReader(ms, Encoding.UTF8);
                    return reader.ReadToEnd();
                }
                else
                {
                    var reader = new StreamReader(s, Encoding.UTF8);
                    return reader.ReadToEnd();
                }
            }
        }
    }
}
